<?php
set_time_limit(180);

if(!function_exists('mb_str_replace')) {
	function mb_str_replace($search, $replace, $subject) {
		if(is_array($subject)) {
			$ret = array();
			foreach($subject as $key => $val) {
				$ret[$key] = mb_str_replace($search, $replace, $val);
			}
			return $ret;
		}

		foreach((array) $search as $key => $s) {
			if($s == '') {
				continue;
			}
			$r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : '');
			$pos = mb_strpos($subject, $s);
			while($pos !== false) {
				$subject = mb_substr($subject, 0, $pos) . $r . mb_substr($subject, $pos + mb_strlen($s));
				$pos = mb_strpos($subject, $s, $pos + mb_strlen($r));
			}
		}
		return $subject;
	}
}

if (function_exists('mb_substr_replace') === false){
	function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = null){
		if (extension_loaded('mbstring') === true){
			$string_length = (is_null($encoding) === true) ? mb_strlen($string) : mb_strlen($string, $encoding);
		 
			if ($start < 0){
				$start = max(0, $string_length + $start);
			} else if ($start > $string_length){
				$start = $string_length;
			}
		 
			if ($length < 0) {
				$length = max(0, $string_length - $start + $length);
			} else if ((is_null($length) === true) || ($length > $string_length)){
				$length = $string_length;
			}
		 
			if (($start + $length) > $string_length){
				$length = $string_length - $start;
			}
		 
			if (is_null($encoding) === true){
				return mb_substr($string, 0, $start) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length);
			}
		 
			return mb_substr($string, 0, $start, $encoding) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length, $encoding);
		}
	 
		return (is_null($length) === true) ? substr_replace($string, $replacement, $start) : substr_replace($string, $replacement, $start, $length);
	}
}

function make_absolute_path($path, $domain, $base_url) {
	if(preg_match("/^[a-z]+:\/\//i", $path)) return $path;
	if(preg_match("/^\//", $path)) return $domain . $path;
	return $base_url . "/" . $path;  
}

function get_domain_prefix($url) {
	if(preg_match("/^(.*:\/\/[^\/]+)/", $url, $arr)) return $arr[1];
	return false;
}

function get_base_url($url) {
	if(preg_match("/^(.*\/[^.\/]+)$/", $url, $arr)) return $arr[1];
	if(preg_match("/^(.*)\//", $url, $arr)) return $arr[1];
	return false;
}

function replace_relative_paths($html, $url) {
	$domain = get_domain_prefix($url);
	$base_url = get_base_url($url);
	
	$to_include = '<base href="'. $base_url .'/">';
	if(preg_match("/(<head>)/i", $html, $arr)) {
			$html = str_replace($arr[1], "<head>". $to_include . "\n", $html);
	} else {
		$html = "<head>". $to_include ."\n</head>\n" . $html;
	}

	if(preg_match_all("/ ((href|src|action|background)=(['\"])(.*?)\\3)/", $html, $matches, PREG_SET_ORDER)) {
		foreach($matches as $arr) {
			$path = $arr[4];
			$absolute_path = make_absolute_path($path, $domain, $base_url);
			$replace = $arr[2] . "=" . $arr[3] . $absolute_path . $arr[3];
			$html = str_replace($arr[1], $replace, $html);
		}
	}
	
	return $html;
}

function CURL($url, $post = null, $retries = 3) {
	$curl = curl_init($url);

	if (is_resource($curl) === true) {
		curl_setopt($curl, CURLOPT_FAILONERROR, true);
		curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

		if (isset($post) === true) {
			curl_setopt($curl, CURLOPT_POST, true);
			curl_setopt($curl, CURLOPT_POSTFIELDS, (is_array($post) === true) ? http_build_query($post, '', '&') : $post);
		}

		$result = false;
		while (($result === false) && (--$retries > 0)){
			$result = curl_exec($curl);
		}
		curl_close($curl);
	}

	return $result;
}

function convert($size){
	$unit = array('b','kb','mb','gb','tb','pb');
	return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}

define("ALLOWED_NAMES", 1000);
include_once("class.badsectors.php");

$url = $_REQUEST['url'];
$s = ($_REQUEST['service'] != "") ? $_REQUEST['service'] : "gbif-tf";
if (trim($url) == "") exit();

$services["gbif-tf"] = "http://ecat-dev.gbif.org/tf?type=url&format=json&input={input}";
$services["gbif-lucene"] = "http://ecat-dev.gbif.org/ws/indexer?type=url&input={input}&format=json";
$services["ubio-tf"] = "http://namefinding.ubio.org/find?type=url&client=taxonfinder&format=json&input={input}";
$services["ubio-neti"] = "http://namefinding.ubio.org/find?type=url&client=neti&format=json&input={input}";

$erase = array("[", "]");

$request = str_replace("{input}", urlencode($url), $services[$s]);
$json = CURL($request);
#echo convert(memory_get_usage()) . "<br>\n";

if ($_REQUEST['output'] == "json") {
	header('Content-type: application/json');
	$nList = array();
	$list = null;
	$json = json_decode($json, true);
	foreach($json["names"] as $name) {
		$name['scientificName'] = str_replace($erase, "", $name['scientificName']);
		if (!$nList[$name['scientificName']]) {
			$nList[$name['scientificName']] = $name;
		}
	}
	$json = json_encode(array("names" => array_values($nList)));
	print $json;
	exit();
}

$json = json_decode($json, true);
#echo convert(memory_get_usage()) . "<br>\n";
if (count($json["names"]) > ALLOWED_NAMES) {
	print "<p style=\"font-family: arial; font-size:14px\">While scanning this webpage we have found " . number_format(count($json["names"]), 0, ".", ",") . " names.  Unfortunately we have an allowance of " . number_format(ALLOWED_NAMES, 0, ".", ",") . " names.  This document is just too large to visually show you this document.  We apologize for this.  We suggest going to http://tools.gbif.org and try one of our other name finding tools.</p>";
	exit();
}
$html = CURL($url);
#echo convert(memory_get_usage()) . "<br>\n";

$enc = mb_detect_encoding($html);
$bs = new BadSectors($html, $enc);
#echo convert(memory_get_usage()) . "<br>\n";

$list = array();
for($i = count($json['names']); $i >= 0; $i--) {
#print_r($json['names'][$i]);
	if ($s == 'ubio-neti') {
		$json['names'][$i]['offsetStart']++;
	}

	if (isset($json['names'][$i]['offsetStart']) && $bs->isSafe($json['names'][$i]['offsetStart'])) {

		$json['names'][$i]["scientificName"] = strip_tags(mb_str_replace($erase, "", $json['names'][$i]["scientificName"]));
		$repl = "<span class=\"tt-sciname\" id=\"tt-id-" . $i . "\" scientificName=\"" . $json['names'][$i]["scientificName"] . "\" verbatim=\"" . strip_tags($json['names'][$i]["verbatim"]) . "\">" . strip_tags($json['names'][$i]["verbatim"]) . "</span><span class=\"tt-remove\">&nbsp;&nbsp;</span>";

		$val = mb_substr($html, $json['names'][$i]['offsetStart'], $json['names'][$i]['offsetEnd'] - $json['names'][$i]['offsetStart'], $enc);
		if ($val === $json['names'][$i]["verbatim"]) {
			$html = mb_substr_replace($html, $repl, $json['names'][$i]['offsetStart'], $json['names'][$i]['offsetEnd'] - $json['names'][$i]['offsetStart'], $enc);
		} else {
			$val = substr($html, $json['names'][$i]['offsetStart'], $json['names'][$i]['offsetEnd'] - $json['names'][$i]['offsetStart']);
			if ($val === $json['names'][$i]["verbatim"]) {
				$html = substr_replace($html, $repl, $json['names'][$i]['offsetStart'], $json['names'][$i]['offsetEnd'] - $json['names'][$i]['offsetStart']);
			}			
		}
	}
}
$html = replace_relative_paths($html, $url);
print $html;
?>